﻿using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Marbles.Data
{
    public class DataSourceCommand
    {
        private string _CommandText;
        private Dictionary<string, object> _Parameters;

        public DataSourceCommand()
        {
            this._CommandText = string.Empty;
            this._CommandText = string.Empty;
            this._Parameters = new Dictionary<string, object>();
        }

        public DataSourceCommand(string CommandText)
        {
            this._CommandText = string.Empty;
            this._CommandText = CommandText;
            this._Parameters = new Dictionary<string, object>();
        }

        private void InternalAddParameter(string Name, object Value)
        {
            if (this._Parameters.ContainsKey(Name))
            {
                this._Parameters[Name] = Value;
            }
            else
            {
                this._Parameters.Add(Name, Value);
            }

        }

        public void AddParameter(string Name, object Value)
        {
            InternalAddParameter(Name, Value);
        }

        public void AddBinaryParameter(string Name, Stream Stream)
        {
            BinaryReader sr = new BinaryReader(Stream);
            byte[] data = new byte[Stream.Length];
            int offset = 0;
            int remaining = data.Length;

            while (remaining > 0)
            {
                int read = sr.Read(data, offset, BaseDataSource.BinaryStreamBufferSize);
                if (read <= 0) { throw new EndOfStreamException("End of stream reached."); }
                remaining -= read;
                offset += read;
            }

            sr.Close();

            InternalAddParameter(Name, data);
        }

        public void AddBinaryParameter(string Name, string Filename)
        {
            FileStream sr = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            byte[] data = new byte[sr.Length];
            int offset = 0;
            int remaining = data.Length;

            while (remaining > 0)
            {
                int read = sr.Read(data, offset, BaseDataSource.BinaryStreamBufferSize);
                if (read <= 0) { throw new EndOfStreamException("End of stream reached."); }
                remaining -= read;
                offset += read;
            }

            sr.Close();

            InternalAddParameter(Name, data);
        }

        public string CommandText
        {
            get
            {
                return this._CommandText;
            }
            set
            {
                this._CommandText = value;
            }
        }

        public Dictionary<string, object> Parameters
        {
            get
            {
                return this._Parameters;
            }
        }

        public DataSourceCommand Clone()
        {
            DataSourceCommand cmd = new DataSourceCommand(this.CommandText);
            foreach (string p in this._Parameters.Keys)
            {
                cmd.Parameters.Add(p, this._Parameters[p]);
            }

            return cmd;
        }
    }

}
